package cn.ctyun.ipush.service.impl;

import cn.ctyun.ipush.constant.ResultInfo;
import cn.ctyun.ipush.dao.TaskDao;
import cn.ctyun.ipush.dto.ResultDto;
import cn.ctyun.ipush.model.*;
import cn.ctyun.ipush.service.ScheduleJobService;
import cn.ctyun.ipush.service.TaskDetailService;
import cn.ctyun.ipush.service.TaskService;
import cn.ctyun.ipush.utils.DBUtils;
import cn.ctyun.ipush.vo.DataSourceVo;
import cn.ctyun.ipush.vo.TaskVo;

import cn.ctyun.ipush.web.user.bo.UserModel;
import com.dexcoder.commons.bean.BeanConverter;
import com.dexcoder.commons.utils.UUIDUtils;
import com.dexcoder.dal.JdbcDao;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: user
 * Date: 16-6-11
 * Time: 下午5:40
 * To change this template use File | Settings | File Templates.
 */
@Service("taskService")
public class TaskServiceImpl implements TaskService {

    /* 日志对象 */
    private final Logger LOG = LoggerFactory.getLogger(TaskServiceImpl.class);

    /* db访问对象 */
    @Autowired
    private TaskDao taskDao;

    /* 结果对象 */
    private ResultDto resultVo = new ResultDto();

    @Autowired
    private TaskDetailService taskDetailService;

    @Autowired
    private ScheduleJobService scheduleJobService;

    @Autowired
    private JdbcDao jdbcDao;


    /**
     * 任务修改，通常修改定时器的时间,执行的sql，Excel模板
     *
     * @param taskVo
     * @return
     */
    @Override
    @Transactional
    public ResultDto update(TaskVo taskVo) {
        try {
            //设置oracel驱动
            taskVo.getDataSource().setDataSourceDriver("oracle.jdbc.driver.OracleDriver");
            taskVo.getDataSource().setConnMaxCount("5");
            //check data
            //task detail is empty
            if (null == taskVo.getTaskDetail())
                return resultVo.setInfo("task Detail not config").setStatus(ResultInfo.failure);

            //task identity is empty
            if (null == taskVo.getTaskDetail().getTaskGroupName() || null == taskVo.getTaskDetail().getTaskName() || null == taskVo.getTaskDetail().getCronExpression())
                return resultVo.setInfo("task Detail not complete ").setStatus(ResultInfo.failure);

            //定时时间变化,首先删除当前job，然后最后在创建新的Job
            TaskVo newTaskVo = taskDao.getNewTaskVoFromTaskVo(taskVo);//修改后的完整的taskVo对象
            TaskVo dbTaskVo = taskDao.getDbTaskVoByTaskId(taskVo.getTaskModelId());

            if (!taskVo.getTaskDetail().getCronExpression().equals(dbTaskVo.getTaskDetail().getCronExpression())) {
                //删除job，更新Db内job，创建Job
                scheduleJobService.delete(taskVo.getTaskModelId());
                //更新 taskmodel、taskDetailModel
                taskDao.update(newTaskVo.getTargetObject(TaskModel.class));
                taskDetailService.update(newTaskVo.getTaskDetail());
                //注意此处不更新缓存，在job里判断并更新缓存
                //创建Job
                scheduleJobService.insert(newTaskVo);

            } else {
                //更新 taskmodel、taskDetailModel
                taskDao.update(newTaskVo.getTargetObject(TaskModel.class));
                taskDetailService.update(newTaskVo.getTaskDetail());
            }
            return resultVo.setStatus(ResultInfo.success).setInfo("update task success");
        } catch (Exception ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }


    /**
     * 保存任务配置参数，包括 数据库记录保存 创建job、连接缓存
     *
     * @param taskVo
     */
    @Override
    @Transactional
    public ResultDto save(TaskVo taskVo) {
        try {
            //check data
            //task detail is empty
            if (null == taskVo.getTaskDetail())
                return resultVo.setInfo("task Detail not config").setStatus(ResultInfo.failure);

            //task identity is empty
            if (null == taskVo.getTaskDetail().getTaskGroupName() || null == taskVo.getTaskDetail().getTaskAliasName() || null == taskVo.getTaskDetail().getCronExpression())
                return resultVo.setInfo("task Detail not complete").setStatus(ResultInfo.failure);

            //task is exist ,taskGroupname + taskAliasName
            if (taskDetailService.isExist(taskVo.getTaskDetail()))
                return resultVo.setInfo("task exists, no repeat adtaskVod").setStatus(ResultInfo.failure);

            //save data to db and need  transaction control
            if (!taskDao.insert(taskVo))
                return resultVo.setInfo("task save fail ").setStatus(ResultInfo.failure);

            // if task is autoStart  1 代表自动执行
            if (taskVo.getTaskDetail().getIsAutoRun().equals("1")) {
                scheduleJobService.insert(taskVo);
            }
            return resultVo.setInfo("task add success ").setStatus(ResultInfo.success);

        } catch (Exception ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }

    /**
     * 删除task 包括 job 连接缓存  数据库记录
     *
     * @param taskId
     * @return
     */
    @Override
    @Transactional
    public ResultDto delete(String taskId) {
        TaskVo taskVo = taskDao.getDbTaskVoByTaskId(taskId);
        //刪除任務，注意刪除連接池中的连接
        if (!StringUtils.isEmpty(taskVo.getTaskModelId())) {
            //删除job
            scheduleJobService.delete(taskVo.getTaskModelId());
            //删除数据库记录 taskModel taskDetail
            taskDao.delete(taskVo.getTaskModelId());
            taskDetailService.delete(taskVo.getTaskDetailId());
            return resultVo.setInfo("task delete success ").setStatus(ResultInfo.success);
        }
        return resultVo.setInfo("task delete fail ").setStatus(ResultInfo.failure);
    }

    /**
     * job 作业中调用
     *
     * @param taskId
     * @return
     */
    public TaskVo getTaskVoByTaskId(String taskId) {
        return taskDao.getDbTaskVoByTaskId(taskId);
    }

    @Override
    public ResultDto runOnce(String taskId) {
        TaskVo taskVo = taskDao.getDbTaskVoByTaskId(taskId);
        try {
            scheduleJobService.runOnce(taskVo.getTaskDetail());
            return resultVo.setInfo("task runOnce success ").setStatus(ResultInfo.success);

        } catch (Exception ex) {
            return resultVo.setInfo("task runOnce fail :" + ex.getMessage()).setStatus(ResultInfo.failure);

        }
    }

    @Override
    public ResultDto pauseTask(String taskId) {
        TaskVo taskVo = taskDao.getDbTaskVoByTaskId(taskId);
        try {
            scheduleJobService.pauseTask(taskVo.getTaskDetail(), taskId);
            return resultVo.setInfo("task pause success ").setStatus(ResultInfo.success);

        } catch (Exception ex) {
            return resultVo.setInfo("task pause fail :" + ex.getMessage()).setStatus(ResultInfo.failure);

        }
    }

    public ResultDto resumeTask(String taskId) {
        TaskVo taskVo = taskDao.getDbTaskVoByTaskId(taskId);
        try {
            scheduleJobService.resumeTask(taskVo.getTaskDetail(), taskId);
            return resultVo.setInfo("task resume success ").setStatus(ResultInfo.success);
        } catch (Exception ex) {
            return resultVo.setInfo("task resume fail :" + ex.getMessage()).setStatus(ResultInfo.failure);
        }
    }

    @Override
    public List<TaskVo> queryListVoByPage(TaskVo taskVo) {
        //分页查询
        int currentPage = taskVo.getCurPage();
        int itemPages = taskVo.getItemsPerPage();
        List<TaskModel> taskModelList = taskDao.queryListByPage(currentPage, itemPages, taskVo);
        List<TaskVo> taskVoList = BeanConverter.convert(TaskVo.class, taskModelList);
        return taskVoList;
    }

    @Override
    public List<TaskModel> queryList(TaskModel taskModel) {
        return taskDao.queryList(taskModel);
    }


    @Override
    public boolean isExist(String taskModelName) {
        if (null == taskDao.querySingleResultByName(taskModelName)) {
            return false;
        } else {
            return true;
        }

    }

    @Override
    public List<TaskDetailModel> getAllTaskDetailByCityId(String cityId) {
        List<TaskDetailModel> taskDetailModelListFinal = new ArrayList<TaskDetailModel>();
        UserModel userModel = new UserModel();
        userModel.setCity(cityId);
        List<UserModel> userModelList = jdbcDao.queryList(userModel);
        if (userModelList.size() > 0) {
            for (UserModel userModel1 : userModelList) {
                TaskDetailModel taskDetailModel = new TaskDetailModel();
                taskDetailModel.setCreateUserid(userModel1.getUserModelId());
                taskDetailModel.setIsDeleted("0");
                List<TaskDetailModel> taskDetailModelList = jdbcDao.queryList(taskDetailModel);
                if (taskDetailModelList.size() > 0) {
                    taskDetailModelListFinal.addAll(taskDetailModelList);
                }
            }
            if(taskDetailModelListFinal.size()>0){
                return  taskDetailModelListFinal;
            }
        }
        return null;
    }
}
